/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill 庄骞 (smallchill@163.com)
 */
package org.springblade.modules.admin.service.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.AllArgsConstructor;
import org.springblade.common.cache.DictCache;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.core.tool.utils.Func;
import org.springblade.modules.admin.dto.MaintainPlanWeeklyReportProjectPageDTO;
import org.springblade.modules.admin.dto.PlanWeeklyListDTO;
import org.springblade.modules.admin.dto.WeeklyReportRepairListPageDTO;
import org.springblade.modules.admin.dto.WeeklyReportRescueListPageDTO;
import org.springblade.modules.admin.entity.BuildingPlanWeeklyReportConfig;
import org.springblade.modules.admin.entity.ElevatorEffected;
import org.springblade.modules.admin.entity.MaintainPlanDayCount;
import org.springblade.modules.admin.entity.MaintainPlanWeeklyReport;
import org.springblade.modules.admin.enums.MaintainPlanContentEnum;
import org.springblade.modules.admin.enums.TaskStatusEnum;
import org.springblade.modules.admin.mapper.MaintainPlanWeeklyReportMapper;
import org.springblade.modules.admin.service.*;
import org.springblade.modules.admin.vo.*;
import org.springblade.modules.system.service.ITenantService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 任务周报 服务实现类
 *
 * @author lsay
 * @since 2024-09-02
 */
@AllArgsConstructor
@Service
public class MaintainPlanWeeklyReportServiceImpl extends BaseServiceImpl<MaintainPlanWeeklyReportMapper, MaintainPlanWeeklyReport> implements IMaintainPlanWeeklyReportService {

	private final IMaintainPlanContentService planContentService;
	private final IMaintainPlanDayCountService planDayCountService;
	private final BuildingPlanWeeklyReportConfigService configService;


	@Override
	public IPage<MaintainPlanWeeklyReportProjectPageVO> maintainPlanWeeklyReportPage(IPage<MaintainPlanWeeklyReportProjectPageVO> page, MaintainPlanWeeklyReportProjectPageDTO maintainPlanWeeklyReportPageDTO) {
		// 查询周报列表
		IPage<MaintainPlanWeeklyReportProjectPageVO> maintainPlanWeeklyReportIPage = baseMapper.selectMaintainPlanWeeklyReportPage(page, maintainPlanWeeklyReportPageDTO);

		// 数据处理：描述处理
		List<MaintainPlanWeeklyReportProjectPageVO> records = maintainPlanWeeklyReportIPage.getRecords();
		if (!Func.isEmpty(records)) {
			records.forEach(r -> {
				maintainPlanWeeklyReportPageDTO.setBuildingId(r.getBuildingId());
				List<MaintainPlanWeeklyReportProjectPageListVO> reportList = baseMapper.selectMaintainPlanWeeklyReportList(maintainPlanWeeklyReportPageDTO);
				if (!Func.isEmpty(reportList)) {
					reportList.forEach(e -> {
						Date weekBeginTime = e.getWeekBeginTime();
						if (!Func.isNull(weekBeginTime)) {
							e.setTimeRangeDesc(getMonthWeekDesc(weekBeginTime));
						}
						// 维修工单完成率描述
						Integer malCount = e.getMalCount();
						Integer malFinishCount = e.getMalFinishCount();
						if (!new Integer("0").equals(malCount) && !Func.isNull(malCount) && !Func.isNull(malFinishCount)) {
							double malFinishRate = calculatePercentage(malFinishCount, malCount);
							e.setMalFinishRateDesc(malFinishRate + "%" + "(" + malFinishCount + "/" + malCount + ")");
						}

						// 维修电梯完成率描述
						Integer malFinishElevatorCount = e.getMalFinishElevatorCount();
						Integer malUnderwayElevatorCount = e.getMalUnderwayElevatorCount();
						Integer repairTotal = null;
						if (!Func.isNull(malFinishElevatorCount) && !Func.isNull(malUnderwayElevatorCount)) {
							repairTotal = malFinishElevatorCount + malUnderwayElevatorCount;
						}
						if (!Func.isNull(repairTotal) && repairTotal > 0) {
							double malFinishElevatorRate = calculatePercentage(malFinishElevatorCount, repairTotal);
							e.setMalElevatorFinishRateDesc(malFinishElevatorRate + "%" + "(" + malFinishElevatorCount + "/" + repairTotal + ")");
						}
						// 救援准时率
						Integer rescueOntimeCount = e.getRescueOntimeCount();
						Integer rescueOvertimeCount = e.getRescueOvertimeCount();
						Integer rescueTotal = null;
						if (!Func.isNull(rescueOntimeCount) && !Func.isNull(rescueOvertimeCount)) {
							rescueTotal = rescueOntimeCount + rescueOvertimeCount;
						}
						if (!Func.isNull(rescueTotal) && rescueTotal > 0) {
							double rescueOnTimeRate = calculatePercentage(rescueOntimeCount, rescueTotal);
							e.setRescueOnTimeRateDesc(rescueOnTimeRate + "%" + "(" + rescueOntimeCount + "/" + rescueTotal + ")");
						}
					});
				}
				r.setReportList(reportList);
			});
		}
		maintainPlanWeeklyReportIPage.setRecords(records);
		return maintainPlanWeeklyReportIPage;
	}

	@Override
	public MaintainPlanWeeklyReportProjectDetailVO maintainPlanWeeklyReportDetail(Long reportId) {
		// 参数校验
		if (Func.isNull(reportId)) {
			throw new ServiceException("参数不能为空");
		}
		MaintainPlanWeeklyReport currentReport = this.getById(reportId);
		Date weekEndTime = currentReport.getWeekEndTime();
		MaintainPlanWeeklyReportProjectDetailVO e = baseMapper.selectMaintainPlanWeeklyReportDetail(reportId, weekEndTime);
		Date weekBeginTime = e.getWeekBeginTime();
		if(!Func.isNull(weekBeginTime)){
			e.setTimeRangeDesc(getMonthWeekDesc(weekBeginTime));
		}
		// 维修工单完成率描述
		Integer malCount = e.getMalCount();
		Integer malFinishCount = e.getMalFinishCount();
		if (!new Integer("0").equals(malCount) && !Func.isNull(malCount) && !Func.isNull(malFinishCount)) {
			double malFinishRate = calculatePercentage(malFinishCount, malCount);
			e.setMalFinishRateDesc(malFinishRate + "%" + "(完成" + malFinishCount + "单/报障" + malCount + "单)");
		}
		// 维修电梯完成率描述
		Integer malFinishElevatorCount = e.getMalFinishElevatorCount();
		Integer malUnderwayElevatorCount = e.getMalUnderwayElevatorCount();
		Integer repairTotal = null;
		if (!Func.isNull(malFinishElevatorCount) && !Func.isNull(malUnderwayElevatorCount)) {
			repairTotal = malFinishElevatorCount + malUnderwayElevatorCount;
		}
		if (!Func.isNull(repairTotal) && repairTotal > 0) {
			double malFinishElevatorRate = calculatePercentage(malFinishElevatorCount, repairTotal);
			e.setMalElevatorFinishRateDesc(malFinishElevatorRate + "%" + "(完成" + malFinishElevatorCount + "台/报障" + repairTotal + "台)");
		}
		// 救援准时率
		Integer rescueOntimeCount = e.getRescueOntimeCount();
		Integer rescueOvertimeCount = e.getRescueOvertimeCount();
		Integer rescueTotal = null;
		if (!Func.isNull(rescueOntimeCount) && !Func.isNull(rescueOvertimeCount)) {
			rescueTotal = rescueOntimeCount + rescueOvertimeCount;
		}
		if (!Func.isNull(rescueTotal) && rescueTotal > 0) {
			double rescueOnTimeRate = calculatePercentage(rescueOntimeCount, rescueTotal);
			e.setRescueOnTimeRateDesc(rescueOnTimeRate + "%" + "(准时" + rescueOntimeCount + "单/困人" + rescueTotal + "单)");
		}
		return e;
	}

	@Override
	public IPage<WeeklyReportRepairListPageVO> planViewRepairListPage(IPage<WeeklyReportRepairListPageVO> page, WeeklyReportRepairListPageDTO weeklyReportRepairListPageDTO) {
		IPage<WeeklyReportRepairListPageVO> weeklyReportRepairListPageVOIPage = baseMapper.planViewRepairListPage(page, weeklyReportRepairListPageDTO);
		List<WeeklyReportRepairListPageVO> records = weeklyReportRepairListPageVOIPage.getRecords();
		// 处理时间描述、故障原因描述
		if(!Func.isEmpty(records)){
			records.forEach(r -> {
				Long arrivalTimeConsuming = r.getArrivalTimeConsuming();
				Long finishTimeConsuming = r.getFinishTimeConsuming();
				if(!Func.isNull(arrivalTimeConsuming)){
					String arrivalTimeDesc = formatTimeDescription(arrivalTimeConsuming);
					r.setArrivalTimeDesc(arrivalTimeDesc);
				}
				if(!Func.isNull(finishTimeConsuming)){
					String finishTimeDesc = formatTimeDescription(finishTimeConsuming);
					r.setFinishTimeDesc(finishTimeDesc);
				}
				String faultCause = r.getFaultCause();
				if(!Func.isNull(faultCause)){
					r.setFaultCauseDesc(repairFaultCauseDesc(faultCause));
				}
			});
		}
		weeklyReportRepairListPageVOIPage.setRecords(records);
		return weeklyReportRepairListPageVOIPage;
	}

	@Override
	public IPage<WeeklyReportRescueListPageVO> planViewRescuePage(IPage<WeeklyReportRescueListPageVO> page, WeeklyReportRescueListPageDTO weeklyReportRescueListPageDTO) {
		IPage<WeeklyReportRescueListPageVO> weeklyReportRescueListPageVOIPage = baseMapper.planViewRescuePage(page, weeklyReportRescueListPageDTO);
		List<WeeklyReportRescueListPageVO> records = weeklyReportRescueListPageVOIPage.getRecords();
		if(!Func.isEmpty(records)){
			List<WeeklyReportRescueListPageVO> onTimeList = records.stream().filter(WeeklyReportRescueListPageVO::getIsOnTime).collect(Collectors.toList());
			int overTimeCountTotal = onTimeList.size();
			Integer onTimeCountTotal = records.size() - overTimeCountTotal;
			records.forEach(r -> {
				Long arriveDuration = r.getArriveDuration();
				Date finishTime = r.getFinishTime();
				Date createTime = r.getCreateTime();
				if(!Func.isNull(arriveDuration)){
					String arrivalTimeDesc = formatTimeDescription(arriveDuration);
					r.setArrivalTimeDesc(arrivalTimeDesc);
				}
				if(!Func.isNull(finishTime) && !Func.isNull(createTime)){
					String finishTimeDesc = formatTimeDescription(finishTime.getTime() - createTime.getTime());
					r.setFinishTimeDesc(finishTimeDesc);
				}
				String faultCauseDesc = r.getFaultCauseDesc();
				if(!Func.isNull(faultCauseDesc)){
					String[] split = faultCauseDesc.split(",");
					// 使用 set 去重
					Set<String> set = new HashSet<>(Arrays.asList(split));
					String[] distinctArr = set.toArray(new String[0]);
					String distinctStr = String.join(",", distinctArr);
					r.setFaultCauseDesc(rescueFaultCauseDesc(distinctStr));
				}
				r.setOnTimeCountTotal(onTimeCountTotal);
				r.setOverTimeCountTotal(overTimeCountTotal);
			});
		}
		weeklyReportRescueListPageVOIPage.setRecords(records);
		return weeklyReportRescueListPageVOIPage;
	}


	/**
	 * 计算百分比并保留个位数
	 *
	 * @param numerator   分子
	 * @param denominator 分母
	 * @return 保留个位数的百分比
	 */
	private double calculatePercentage(double numerator, double denominator) {
		if (denominator == 0) {
			throw new IllegalArgumentException("分母不能为零");
		}
		// 计算百分比并四舍五入到个位数
		return Math.round((numerator / denominator) * 100);
	}

	/**
	 * 根据日期获取月周描述
	 */
	private String getMonthWeekDesc(Date weekBeginTime) {
		int startWeekOfMonth = DateUtil.weekOfMonth(weekBeginTime);
		// 通过weekBeginTime获取年份和月份
		LocalDate beginDate = weekBeginTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
		// 通过weekBeginTime获取年份和月份
		int year = beginDate.getYear();
		int month = beginDate.getMonthValue();
		// 计算月份的第一周的周一
		LocalDate firstDayOfMonth = beginDate.with(TemporalAdjusters.firstDayOfMonth());
		LocalDate firstMonday = firstDayOfMonth.with(TemporalAdjusters.nextOrSame(DayOfWeek.MONDAY));
		// 计算给定日期是月份中的第几周
		int weekOfMonth = 0;
		LocalDate current = firstMonday;
		while (current.isBefore(beginDate) || current.equals(beginDate)) {
			weekOfMonth++;
			current = current.plusWeeks(1);
		}
		// 计算周的开始和结束日期
        LocalDate weekEnd = beginDate.plusDays(6);
		// 构建最终统计周期描述
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd周", Locale.CHINA);
        return String.format("%d年%d月%d周(%s-%s)",
			year, month, weekOfMonth,
			beginDate.format(DateTimeFormatter.ofPattern("MM/dd")),
			weekEnd.format(DateTimeFormatter.ofPattern("MM/dd"))
		);
	}

	private String formatTimeDescription(long totalMilliseconds) {
		// 定义常量
		int millisecondsPerMinute = 1000 * 60;
		int millisecondsPerHour = millisecondsPerMinute * 60;
		int millisecondsPerDay = millisecondsPerHour * 24;

		// 计算天数、小时数和分钟数
		long days = totalMilliseconds / millisecondsPerDay;
		totalMilliseconds %= millisecondsPerDay;

		long hours = totalMilliseconds / millisecondsPerHour;
		totalMilliseconds %= millisecondsPerHour;

		long minutes = totalMilliseconds / millisecondsPerMinute;

		// 根据天数返回不同的格式
		if (days > 0 || hours >= 12) {
			return String.format("%d天%d小时%d分钟", days, hours, minutes);
		} else {
			return String.format("%d小时%d分钟", hours, minutes);
		}
	}

	private String rescueFaultCauseDesc(String faultCause) {
		return faultCause.replaceAll(",", "/");
	}

	private String rescueFaultCauseDescElevatorView(String faultCause){
		return faultCause.replaceAll(",", "、");
	}

	private String repairFaultCauseDesc(String faultCause) {
		String[] faultCauseArr = faultCause.split(",");
		StringBuilder faultCauseStr = new StringBuilder();
		List<String> faultCauseList = Arrays.asList(faultCauseArr);
		faultCauseList.forEach(f -> {
			String value = DictCache.getValue("fault_reason", f);
			if(!Func.isNull(value)){
				faultCauseStr.append(value).append("、");
			}
		});
		if(faultCauseStr.length() > 0){
			faultCauseStr.deleteCharAt(faultCauseStr.length() - 1);
		}
		return faultCauseStr.toString();
	}

	@Override
	public MaintainPlanWeeklyReport selectDetail(MaintainPlanWeeklyReport weeklyReport) {
		MaintainPlanWeeklyReport report = baseMapper.selectDetail(weeklyReport);
		return report;
	}

	@Override
	public List<Map<String, Object>> empElevatorList(Long buildingId, Integer typeStatus, Integer status, String startTime, String endTime) {
		List<Map<String,Object>> empElevator = baseMapper.selectEmpElevator(buildingId,typeStatus,startTime,endTime);
		if(typeStatus.equals(MaintainPlanContentEnum.MAINTAIN_WX.getId())){
			// 维修中
			if(status.equals(1)){
				empElevator = empElevator.stream().filter(e -> !String.valueOf(e.get("planStatus")).equals(String.valueOf(TaskStatusEnum.WX_SIGN_FINISH.getStatus()))).collect(Collectors.toList());
			}else {
				empElevator =  empElevator.stream().filter(e -> String.valueOf(e.get("planStatus")).equals(String.valueOf(TaskStatusEnum.WX_SIGN_FINISH.getStatus()))).collect(Collectors.toList());
			}
			empElevator.forEach(e -> {
				List<String> reasonItem = Func.toStrList(String.valueOf(e.get("reasonItem"))).stream().distinct().collect(Collectors.toList());
				String reasonItemValue = reasonItem.stream().map(t -> Func.isNotEmpty(DictCache.getValue("fault_reason",t)) ? DictCache.getValue("fault_reason",t) : "").distinct().collect(Collectors.joining(","));
				e.put("reasonItemValue",reasonItemValue);
			});
			return empElevator;
		}else {
			empElevator.forEach(e -> {
				List<String> reasonItemValue = Func.toStrList(String.valueOf(e.get("reasonItemValue"))).stream().distinct().collect(Collectors.toList());
				e.put("reasonItemValue",reasonItemValue.stream().distinct().collect(Collectors.joining(",")));
			});
			return empElevator;
		}
	}



	@Override
	@Transactional(rollbackFor = Exception.class)
	public Boolean generatePlanWeeklyReport(String weekBeginTime,String weekEndTime) {

		List<MaintainPlanWeeklyReport> reportList = new ArrayList<>();
		if(Func.isEmpty(weekBeginTime)){
			weekBeginTime = DateUtil.format(DateUtil.offsetDay(DateUtil.date(),-7),"yyyy-MM-dd");
		}
		if(Func.isEmpty(weekEndTime)){
			weekEndTime = DateUtil.format(DateUtil.offsetDay(DateUtil.date(),-1),"yyyy-MM-dd");
		}

		String lastWeekBeginTime = DateUtil.format(DateUtil.offsetDay(DateUtil.parse(weekBeginTime,"yyyy-MM-dd"),-7),"yyyy-MM-dd");
		String lastWeekEndTime = DateUtil.format(DateUtil.offsetDay(DateUtil.parse(weekEndTime,"yyyy-MM-dd"),-7),"yyyy-MM-dd");
		// 周工单列表
		List<PlanWeeklyListDTO> weekPlanList = baseMapper.selectPlanList(weekBeginTime,weekEndTime);
		// 上周周报记录
		List<MaintainPlanWeeklyReport> lastWeekPlanList = baseMapper.selectListByDate(lastWeekBeginTime,lastWeekEndTime);
		// 周有效梯
		List<ElevatorEffectedVO> elevatorEffectedList = planContentService.selectElevatorEffectedListByEndDate(weekEndTime);
		// 周工单快照
		List<MaintainPlanDayCount> planDayCounts = baseMapper.selectPlanDayCountByDate(weekBeginTime,weekEndTime);
		// 周停梯统计
		List<ElevatorSimpleInfoVO> elevatorSimpleInfoList = baseMapper.selectElevatorSimpleInfo(weekBeginTime,weekEndTime);
		// 根据租户分组
		List<BuildingPlanWeeklyReportConfig> buildings = configService.selectList(new BuildingPlanWeeklyReportConfig());
		Map<String,List<BuildingPlanWeeklyReportConfig>> tenantGroup = buildings.stream().collect(Collectors.groupingBy(BuildingPlanWeeklyReportConfig::getTenantId));
		String finalWeekBeginTime = weekBeginTime;
		String finalWeekEndTime = weekEndTime;
		tenantGroup.forEach((k0, v0) -> {
			// 需要生成周报的项目
			if(Func.isNotEmpty(v0)){
				v0.forEach(t -> {
					MaintainPlanWeeklyReport lastWeeklyReport = lastWeekPlanList.stream().filter(e -> e.getBuildingId().equals(t.getBuildingId())).findFirst().orElse(null);
					List<ElevatorEffectedVO> buildingElevatorEffectedList = elevatorEffectedList.stream().filter(e -> e.getBuildingId().equals(t.getBuildingId())).collect(Collectors.toList());
					List<Long> elevatorIds = buildingElevatorEffectedList.stream().map(ElevatorEffected::getElevatorId).collect(Collectors.toList());
					List<PlanWeeklyListDTO> buildingPlanList = weekPlanList.stream().filter(e -> e.getBuildingId().equals(t.getBuildingId()) && elevatorIds.contains(e.getElevatorId())).collect(Collectors.toList());
					List<MaintainPlanDayCount> buildingPlanDayCounts = planDayCounts.stream().filter(e -> e.getBuildingId().equals(t.getBuildingId())).collect(Collectors.toList());
					MaintainPlanWeeklyReport report = new MaintainPlanWeeklyReport();
					report.setBuildingId(t.getBuildingId());
					report.setBuildingName(t.getBuildingName());
					report.setTenantId(k0);
					// 有效电梯数
					report.setElevatorCount(elevatorEffectedList.stream().filter(e -> e.getTenantId().equals(k0) && e.getBuildingId().equals(t.getBuildingId())).map(ElevatorEffected::getElevatorId).distinct().count());
					// 故障电梯数
					report.setFaultElevatorCount(buildingPlanList.stream().filter(e -> e.getTypeStatus().equals(MaintainPlanContentEnum.MAINTAIN_WX.getId())).map(PlanWeeklyListDTO::getElevatorId).distinct().count());
					// 上周故障电梯数
					Long lastWeekFaultElevatorCount = 0L;
					if(Func.isNotEmpty(lastWeeklyReport) && Func.isNotEmpty(lastWeeklyReport.getFaultElevatorCount())){
						lastWeekFaultElevatorCount = lastWeeklyReport.getFaultElevatorCount();
					}
					report.setFaultElevatorAddCount(report.getFaultElevatorCount() - lastWeekFaultElevatorCount);
					Map<Long,List<PlanWeeklyListDTO>> elevatorGroup = buildingPlanList.stream().filter(j -> j.getTypeStatus().equals(MaintainPlanContentEnum.MAINTAIN_WX.getId())).collect(Collectors.groupingBy(PlanWeeklyListDTO::getElevatorId));
					// 维修完成电梯数
					Long malFinishElevatorCount = elevatorGroup.entrySet().stream().filter(j -> {
						String statusList = j.getValue().stream().map(m -> String.valueOf(m.getPlanStatus())).distinct().collect(Collectors.joining(","));
						if(statusList.equals(String.valueOf(TaskStatusEnum.WX_SIGN_FINISH.getStatus()))){
							return Boolean.TRUE;
						}else {
							return Boolean.FALSE;
						}
					}).count();
					report.setMalFinishElevatorCount(malFinishElevatorCount);
					// 维修中电梯数
					Long malUnderwayElevatorCount = elevatorGroup.entrySet().stream().filter(j -> {
						String statusList = j.getValue().stream().map(m -> String.valueOf(m.getPlanStatus())).distinct().collect(Collectors.joining(","));
						if(statusList.equals(String.valueOf(TaskStatusEnum.WX_SIGN_FINISH.getStatus()))){
							return Boolean.FALSE;
						}else {
							return Boolean.TRUE;
						}
					}).count();
					report.setMalUnderwayElevatorCount(malUnderwayElevatorCount);
					// 困人电梯数
					report.setRescueElevatorCount(buildingPlanList.stream().filter(e -> e.getTypeStatus().equals(MaintainPlanContentEnum.MAINTAIN_KR.getId())).map(PlanWeeklyListDTO::getElevatorId).distinct().count());
					// 救援次数
					report.setRescueCount(buildingPlanList.stream().filter(e -> e.getTypeStatus().equals(MaintainPlanContentEnum.MAINTAIN_KR.getId())).map(PlanWeeklyListDTO::getPlanId).distinct().count());
					// 上周救援次数
					Long lastRescueCount = 0L;
					if(Func.isNotEmpty(lastWeeklyReport) && Func.isNotEmpty(lastWeeklyReport.getRescueCount())){
						lastRescueCount = lastWeeklyReport.getRescueCount();
					}
					report.setRescueAddCount(report.getRescueCount() - lastRescueCount);
					// 准时救援次数
					report.setRescueOntimeCount(buildingPlanList.stream().filter(e -> e.getTypeStatus().equals(MaintainPlanContentEnum.MAINTAIN_KR.getId())
						&& e.getIsOvertime().equals(3)).map(PlanWeeklyListDTO::getPlanId).distinct().count());
					// 超时救援次数
					report.setRescueOvertimeCount(buildingPlanList.stream().filter(e -> e.getTypeStatus().equals(MaintainPlanContentEnum.MAINTAIN_KR.getId())
						&& !e.getIsOvertime().equals(3)).map(PlanWeeklyListDTO::getPlanId).distinct().count());

					// 维修电梯数每日趋势
					List<Map<String,Object>> initMalElevatorTrend = this.initMalElevatorTrend(finalWeekBeginTime, finalWeekEndTime);
					initMalElevatorTrend.forEach(e -> {
						List<MaintainPlanDayCount> byTimeFilter = buildingPlanDayCounts.stream().filter(j -> DateUtil.format(j.getPlanCreateTime(),"yyyy-MM-dd").equals(String.valueOf(e.get("label")))).collect(Collectors.toList());
						Map<Long,List<MaintainPlanDayCount>> byElevatorGroup = byTimeFilter.stream().collect(Collectors.groupingBy(MaintainPlanDayCount::getElevatorId));
						e.put("v1",byElevatorGroup.entrySet().stream().filter(j -> {
							String statusList = j.getValue().stream().filter(m -> m.getTypeStatus().equals(MaintainPlanContentEnum.MAINTAIN_WX.getId())).map(m -> String.valueOf(m.getPlanStatus())).distinct().collect(Collectors.joining(","));
							if(statusList.equals(String.valueOf(TaskStatusEnum.WX_SIGN_FINISH.getStatus()))){
								return Boolean.TRUE;
							}else {
								return Boolean.FALSE;
							}
						}).count());
						e.put("v2",byElevatorGroup.entrySet().stream().filter(j -> {
							String statusList = j.getValue().stream().filter(m -> m.getTypeStatus().equals(MaintainPlanContentEnum.MAINTAIN_WX.getId())).map(m -> String.valueOf(m.getPlanStatus())).distinct().collect(Collectors.joining(","));
							if(statusList.equals(String.valueOf(TaskStatusEnum.WX_SIGN_FINISH.getStatus()))){
								return Boolean.FALSE;
							}else {
								return Boolean.TRUE;
							}
						}).count());
					});
					report.setMalElevatorTrend(initMalElevatorTrend);

					// 救援次数每日趋势
					List<Map<String,Object>> initRescueTrend = this.initMalElevatorTrend(finalWeekBeginTime, finalWeekEndTime);
					initRescueTrend.forEach(e -> {
						e.put("v1",buildingPlanDayCounts.stream().filter(j -> j.getTypeStatus().equals(MaintainPlanContentEnum.MAINTAIN_KR.getId())
							&& DateUtil.format(j.getPlanEndTime(),"yyyy-MM-dd").equals(String.valueOf(e.get("label")))
							&& j.getTimeliness().equals(3)).map(MaintainPlanDayCount::getPlanId).distinct().count());
						e.put("v2",buildingPlanDayCounts.stream().filter(j -> j.getTypeStatus().equals(MaintainPlanContentEnum.MAINTAIN_KR.getId())
							&& DateUtil.format(j.getPlanEndTime(),"yyyy-MM-dd").equals(String.valueOf(e.get("label")))
							&& !j.getTimeliness().equals(3)).map(MaintainPlanDayCount::getPlanId).distinct().count());
					});
					report.setRescueCountTrend(initRescueTrend);

					// 维修工单未完成及已完成次数
					report.setMalUnderwayCount(buildingPlanList.stream().filter(e -> e.getTypeStatus().equals(MaintainPlanContentEnum.MAINTAIN_WX.getId())
						&& !e.getPlanStatus().equals(TaskStatusEnum.WX_SIGN_FINISH.getStatus())).map(PlanWeeklyListDTO::getPlanId).distinct().count());
					report.setMalFinishCount(buildingPlanList.stream().filter(e -> e.getTypeStatus().equals(MaintainPlanContentEnum.MAINTAIN_WX.getId())
						&& e.getPlanStatus().equals(TaskStatusEnum.WX_SIGN_FINISH.getStatus())).map(PlanWeeklyListDTO::getPlanId).distinct().count());
					report.setMalCount(report.getMalUnderwayCount() + report.getMalFinishCount());

					// 维修故障原因分布
					List<Map<String,Object>> malFaultReasonItemCount = this.initMalFaultReasonItemCount(buildingPlanList);
					report.setMalFaultReasonItemCount(malFaultReasonItemCount);

					// 维修到达耗时
					List<Map<String,Object>> malArriveTimeInitResult = this.initMalArriveTimeCount(buildingPlanList);
					report.setMalArriveTimeCount(malArriveTimeInitResult);

					// 维修完成耗时
					List<Map<String,Object>> malFinishTimeInitResult = this.initMalFinishTimeCount(buildingPlanList);
					report.setMalFinishTimeCount(malFinishTimeInitResult);

					// 故障次数电梯top5
					List<Map<String,Object>> elevatorMalCountTop = this.initElevatorMalCountTop(buildingElevatorEffectedList,buildingPlanList);
					report.setElevatorMalCountTop(elevatorMalCountTop);

					// 停梯时长电梯top5
					List<Map<String,Object>> elevatorStopTop = this.initElevatorStopTop(elevatorIds,elevatorSimpleInfoList);
					report.setElevatorStopTimeTop(elevatorStopTop);

					// 救援原因分布
					List<Map<String,Object>> rescueReasonItemCount = this.initRescueReasonItemCount(buildingPlanList);
					report.setRescueFaultReasonItemCount(rescueReasonItemCount);

					// 救援到达用时
					List<Map<String,Object>> rescueArriveTimeInitResult = this.initRescueArriveTimeCount(buildingPlanList);
					report.setRescueArriveCount(rescueArriveTimeInitResult);

					// 救援完成用时
					List<Map<String,Object>> rescueFinishTimeInitResult = this.initRescueFinishTimeCount(buildingPlanList);
					report.setRescueFinishCount(rescueFinishTimeInitResult);

					// 电梯困人排行
					List<Map<String,Object>> elevatorRescueCountTop = this.initElevatorRescueCountTop(buildingElevatorEffectedList,buildingPlanList);
					report.setElevatorRescueCountTop(elevatorRescueCountTop);

					// 周报时间
					report.setWeekBeginTime(DateUtil.parse(finalWeekBeginTime,"yyyy-MM-dd"));
					report.setWeekEndTime(DateUtil.parse(finalWeekEndTime,"yyyy-MM-dd"));

					// 记录时间
					report.setRecordDate(DateUtil.date());

					reportList.add(report);
				});
			}
		});
		return super.saveBatch(reportList);
	}

	private List<Map<String, Object>> initRescueReasonItemCount(List<PlanWeeklyListDTO> buildingPlanList) {
		List<Map<String,Object>> result = new ArrayList<>();
		if(Func.isNotEmpty(buildingPlanList)){
			List<String> reasonItemList = buildingPlanList.stream().filter(e -> e.getTypeStatus().equals(MaintainPlanContentEnum.MAINTAIN_KR.getId())).map(PlanWeeklyListDTO::getReasonItem).collect(Collectors.toList());
			List<String> reasons = Func.toStrList(String.join(",",reasonItemList));
			List<String> reasonDistinct = reasons.stream().distinct().collect(Collectors.toList());
			reasonDistinct.forEach(e -> {
				if(Func.isNotEmpty(DictCache.getValue("rescue",e))){
					Map<String,Object> map = new HashMap<>();
					map.put("label", DictCache.getValue("rescue",e));
					map.put("v1",buildingPlanList.stream().filter(t -> Func.toStrList(t.getReasonItem()).contains(e)).count());
					result.add(map);
				}
			});
		}
		return result;
	}

	private List<Map<String, Object>> initMalFaultReasonItemCount(List<PlanWeeklyListDTO> buildingPlanList) {
		List<Map<String,Object>> result = new ArrayList<>();
		if(Func.isNotEmpty(buildingPlanList)){
			List<String> reasonItemList = buildingPlanList.stream().filter(e -> e.getTypeStatus().equals(MaintainPlanContentEnum.MAINTAIN_WX.getId())).map(PlanWeeklyListDTO::getReasonItem).collect(Collectors.toList());
			List<String> reasons = Func.toStrList(String.join(",",reasonItemList));
			List<String> reasonDistinct = reasons.stream().distinct().collect(Collectors.toList());
			reasonDistinct.forEach(e -> {
				if(Func.isNotEmpty(DictCache.getValue("fault_reason",e))){
					Map<String,Object> map = new HashMap<>();
					map.put("label", DictCache.getValue("fault_reason",e));
					map.put("v1",buildingPlanList.stream().filter(t -> Func.toStrList(t.getReasonItem()).contains(e)).count());
					result.add(map);
				}
			});
		}
		return result;
	}

	private List<Map<String, Object>> initElevatorStopTop(List<Long> elevatorIds, List<ElevatorSimpleInfoVO> elevatorSimpleInfoList) {
		List<Map<String,Object>> result = new ArrayList<>();
		if(Func.isNotEmpty(elevatorIds)){
			List<Map<String, Object>> finalResult = result;
			elevatorSimpleInfoList.forEach(e -> {
				if(elevatorIds.contains(e.getElevatorId())){
					Map<String,Object> map = new HashMap<>();
					map.put("label",e.getElevatorAddress());
					map.put("v1",e.getElevatorStopDuration()/60);
					finalResult.add(map);
				}
			});
			result = finalResult.stream().sorted((o1,o2) -> Long.compare(Long.parseLong(String.valueOf(o2.get("v1"))),Long.parseLong(String.valueOf(o1.get("v1"))))).collect(Collectors.toList());
			// 取top5
			if (result.size() > 5) {
				result = result.stream().limit(5).collect(Collectors.toList());
			}
		}
		return result;
	}

	private List<Map<String, Object>> initElevatorMalCountTop(List<ElevatorEffectedVO> buildingElevatorEffectedList, List<PlanWeeklyListDTO> buildingPlanList) {
		List<Map<String,Object>> result = new ArrayList<>();
		if(Func.isNotEmpty(buildingElevatorEffectedList)){
			List<Map<String, Object>> finalResult = result;
			buildingElevatorEffectedList.forEach(e -> {
				Map<String,Object> map = new HashMap<>(2);
				map.put("label",e.getElevatorAddress());
				map.put("v1",buildingPlanList.stream().filter(t -> t.getElevatorId().equals(e.getElevatorId())
					&& t.getTypeStatus().equals(MaintainPlanContentEnum.MAINTAIN_WX.getId())).map(PlanWeeklyListDTO::getPlanId).distinct().count());
				finalResult.add(map);
			});
			result = finalResult.stream().sorted((o1,o2) -> Long.compare(Long.parseLong(String.valueOf(o2.get("v1"))),Long.parseLong(String.valueOf(o1.get("v1"))))).collect(Collectors.toList());
			// 取top5
			if (result.size() > 5) {
				result = result.stream().limit(5).collect(Collectors.toList());
			}
		}
		return result;
	}

	private List<Map<String, Object>> initElevatorRescueCountTop(List<ElevatorEffectedVO> buildingElevatorEffectedList, List<PlanWeeklyListDTO> buildingPlanList) {
		List<Map<String,Object>> result = new ArrayList<>();
		if(Func.isNotEmpty(buildingElevatorEffectedList)){
			List<Map<String, Object>> finalResult = result;
			buildingElevatorEffectedList.forEach(e -> {
				Map<String,Object> map = new HashMap<>(2);
				map.put("label",e.getElevatorAddress());
				map.put("v1",buildingPlanList.stream().filter(t -> t.getElevatorId().equals(e.getElevatorId())
				&& t.getTypeStatus().equals(MaintainPlanContentEnum.MAINTAIN_KR.getId())).map(PlanWeeklyListDTO::getPlanId).distinct().count());
				finalResult.add(map);
			});
			result = finalResult.stream().sorted((o1,o2) -> Long.compare(Long.parseLong(String.valueOf(o2.get("v1"))),Long.parseLong(String.valueOf(o1.get("v1"))))).collect(Collectors.toList());
			// 取top5
			if (result.size() > 5) {
				result = result.stream().limit(5).collect(Collectors.toList());
			}
		}
		return result;
	}

	private List<Map<String, Object>> initRescueFinishTimeCount(List<PlanWeeklyListDTO> buildingPlanList) {
		List<Map<String,Object>> result = new ArrayList<>();
		String[] labelArr = {"<=20","20-25","25-30","30-35","35-40",">40"};
		for (String label : labelArr) {
			Map<String,Object> map = new HashMap<>(2);
			map.put("label",label);
			map.put("v1",0);
			if(labelArr[0].equals(label)){
				map.put("v1",buildingPlanList.stream().filter(e -> e.getTypeStatus().equals(MaintainPlanContentEnum.MAINTAIN_KR.getId())
					&& e.getPlanStatus().equals(TaskStatusEnum.JY_RESCUE.getStatus())
					&& e.getPlanEndTime().getTime() - e.getPlanBeginTime().getTime() <= 20*60*1000).map(PlanWeeklyListDTO::getPlanId).distinct().count());
			}
			if(labelArr[1].equals(label)){
				map.put("v1",buildingPlanList.stream().filter(e -> e.getTypeStatus().equals(MaintainPlanContentEnum.MAINTAIN_KR.getId())
					&& e.getPlanStatus().equals(TaskStatusEnum.JY_RESCUE.getStatus())
					&& e.getPlanEndTime().getTime() - e.getPlanBeginTime().getTime() > 20*60*1000
					&& e.getPlanEndTime().getTime() - e.getPlanBeginTime().getTime() <= 25*60*1000).map(PlanWeeklyListDTO::getPlanId).distinct().count());
			}
			if(labelArr[2].equals(label)){
				map.put("v1",buildingPlanList.stream().filter(e -> e.getTypeStatus().equals(MaintainPlanContentEnum.MAINTAIN_KR.getId())
					&& e.getPlanStatus().equals(TaskStatusEnum.JY_RESCUE.getStatus())
					&& e.getPlanEndTime().getTime() - e.getPlanBeginTime().getTime() > 25*60*1000
					&& e.getPlanEndTime().getTime() - e.getPlanBeginTime().getTime() <= 30*60*1000).map(PlanWeeklyListDTO::getPlanId).distinct().count());
			}
			if(labelArr[3].equals(label)){
				map.put("v1",buildingPlanList.stream().filter(e -> e.getTypeStatus().equals(MaintainPlanContentEnum.MAINTAIN_KR.getId())
					&& e.getPlanStatus().equals(TaskStatusEnum.JY_RESCUE.getStatus())
					&& e.getPlanEndTime().getTime() - e.getPlanBeginTime().getTime() > 30*60*1000
					&& e.getPlanEndTime().getTime() - e.getPlanBeginTime().getTime() <= 35*60*1000).map(PlanWeeklyListDTO::getPlanId).distinct().count());
			}
			if(labelArr[4].equals(label)){
				map.put("v1",buildingPlanList.stream().filter(e -> e.getTypeStatus().equals(MaintainPlanContentEnum.MAINTAIN_KR.getId())
					&& e.getPlanStatus().equals(TaskStatusEnum.JY_RESCUE.getStatus())
					&& e.getPlanEndTime().getTime() - e.getPlanBeginTime().getTime() > 35*60*1000
					&& e.getPlanEndTime().getTime() - e.getPlanBeginTime().getTime() <= 40*60*1000).map(PlanWeeklyListDTO::getPlanId).distinct().count());
			}
			if(labelArr[5].equals(label)){
				map.put("v1",buildingPlanList.stream().filter(e -> e.getTypeStatus().equals(MaintainPlanContentEnum.MAINTAIN_KR.getId())
					&& e.getPlanStatus().equals(TaskStatusEnum.JY_RESCUE.getStatus())
					&& e.getPlanEndTime().getTime() - e.getPlanBeginTime().getTime() > 40*60*1000).map(PlanWeeklyListDTO::getPlanId).distinct().count());
			}
			result.add(map);
		}
		return result;
	}

	private List<Map<String, Object>> initRescueArriveTimeCount(List<PlanWeeklyListDTO> buildingPlanList) {
		List<Map<String,Object>> result = new ArrayList<>();
		String[] labelArr = {"<=10","10-15","15-20","20-25","25-30",">30"};
		for (String label : labelArr) {
			Map<String,Object> map = new HashMap<>(2);
			map.put("label",label);
			map.put("v1",0);
			if(labelArr[0].equals(label)){
				map.put("v1",buildingPlanList.stream().filter(e -> e.getTypeStatus().equals(MaintainPlanContentEnum.MAINTAIN_KR.getId())
					&& Func.isNotEmpty(e.getArriveDuration())
					&& e.getArriveDuration() <= 10*60*1000).map(PlanWeeklyListDTO::getPlanId).distinct().count());
			}
			if(labelArr[1].equals(label)){
				map.put("v1",buildingPlanList.stream().filter(e -> e.getTypeStatus().equals(MaintainPlanContentEnum.MAINTAIN_KR.getId())
					&& Func.isNotEmpty(e.getArriveDuration())
					&& e.getArriveDuration() > 10*60*1000
					&& e.getArriveDuration() <= 15*60*1000).map(PlanWeeklyListDTO::getPlanId).distinct().count());
			}
			if(labelArr[2].equals(label)){
				map.put("v1",buildingPlanList.stream().filter(e -> e.getTypeStatus().equals(MaintainPlanContentEnum.MAINTAIN_KR.getId())
					&& Func.isNotEmpty(e.getArriveDuration())
					&& e.getArriveDuration() > 15*60*1000
					&& e.getArriveDuration() <= 20*60*1000).map(PlanWeeklyListDTO::getPlanId).distinct().count());
			}
			if(labelArr[3].equals(label)){
				map.put("v1",buildingPlanList.stream().filter(e -> e.getTypeStatus().equals(MaintainPlanContentEnum.MAINTAIN_KR.getId())
					&& Func.isNotEmpty(e.getArriveDuration())
					&& e.getArriveDuration() > 20*60*1000
					&& e.getArriveDuration() <= 25*60*1000).map(PlanWeeklyListDTO::getPlanId).distinct().count());
			}
			if(labelArr[4].equals(label)){
				map.put("v1",buildingPlanList.stream().filter(e -> e.getTypeStatus().equals(MaintainPlanContentEnum.MAINTAIN_KR.getId())
					&& Func.isNotEmpty(e.getArriveDuration())
					&& e.getArriveDuration() > 25*60*1000
					&& e.getArriveDuration() <= 30*60*1000).map(PlanWeeklyListDTO::getPlanId).distinct().count());
			}
			if(labelArr[5].equals(label)){
				map.put("v1",buildingPlanList.stream().filter(e -> e.getTypeStatus().equals(MaintainPlanContentEnum.MAINTAIN_KR.getId())
					&& Func.isNotEmpty(e.getArriveDuration())
					&& e.getArriveDuration() > 30*60*1000).map(PlanWeeklyListDTO::getPlanId).distinct().count());
			}
			result.add(map);
		}
		return result;
	}

	private List<Map<String, Object>> initMalFinishTimeCount(List<PlanWeeklyListDTO> buildingPlanList) {
		List<Map<String,Object>> result = new ArrayList<>();
		String[] labelArr = {"<=90","90-120","120-150","150-180",">180"};
		for (String label : labelArr) {
			Map<String,Object> map = new HashMap<>(2);
			map.put("label",label);
			map.put("v1",0);
			if(labelArr[0].equals(label)){
				map.put("v1",buildingPlanList.stream().filter(e -> e.getTypeStatus().equals(MaintainPlanContentEnum.MAINTAIN_WX.getId())
					&& e.getPlanStatus().equals(TaskStatusEnum.WX_SIGN_FINISH.getStatus())
					&& e.getPlanEndTime().getTime() - e.getPlanCreateTime().getTime() <= 90*60*1000).map(PlanWeeklyListDTO::getPlanId).distinct().count());
			}
			if(labelArr[1].equals(label)){
				map.put("v1",buildingPlanList.stream().filter(e -> e.getTypeStatus().equals(MaintainPlanContentEnum.MAINTAIN_WX.getId())
					&& e.getPlanStatus().equals(TaskStatusEnum.WX_SIGN_FINISH.getStatus())
					&& e.getPlanEndTime().getTime() - e.getPlanCreateTime().getTime() > 90*60*1000
					&& e.getPlanEndTime().getTime() - e.getPlanCreateTime().getTime() <= 120*60*1000).map(PlanWeeklyListDTO::getPlanId).distinct().count());
			}
			if(labelArr[2].equals(label)){
				map.put("v1",buildingPlanList.stream().filter(e -> e.getTypeStatus().equals(MaintainPlanContentEnum.MAINTAIN_WX.getId())
					&& e.getPlanStatus().equals(TaskStatusEnum.WX_SIGN_FINISH.getStatus())
					&& e.getPlanEndTime().getTime() - e.getPlanCreateTime().getTime() > 120*60*1000
					&& e.getPlanEndTime().getTime() - e.getPlanCreateTime().getTime() <= 150*60*1000).map(PlanWeeklyListDTO::getPlanId).distinct().count());
			}
			if(labelArr[3].equals(label)){
				map.put("v1",buildingPlanList.stream().filter(e -> e.getTypeStatus().equals(MaintainPlanContentEnum.MAINTAIN_WX.getId())
					&& e.getPlanStatus().equals(TaskStatusEnum.WX_SIGN_FINISH.getStatus())
					&& e.getPlanEndTime().getTime() - e.getPlanCreateTime().getTime() > 150*60*1000
					&& e.getPlanEndTime().getTime() - e.getPlanCreateTime().getTime() <= 180*60*1000).map(PlanWeeklyListDTO::getPlanId).distinct().count());
			}
			if(labelArr[4].equals(label)){
				map.put("v1",buildingPlanList.stream().filter(e -> e.getTypeStatus().equals(MaintainPlanContentEnum.MAINTAIN_WX.getId())
					&& e.getPlanStatus().equals(TaskStatusEnum.WX_SIGN_FINISH.getStatus())
					&& e.getPlanEndTime().getTime() - e.getPlanCreateTime().getTime() > 180*60*1000).map(PlanWeeklyListDTO::getPlanId).distinct().count());
			}
			result.add(map);
		}
		return result;
	}

	private List<Map<String, Object>> initMalArriveTimeCount(List<PlanWeeklyListDTO> buildingPlanList) {
		List<Map<String,Object>> result = new ArrayList<>();
		String[] labelArr = {"<=30","30-60","60-90","90-120",">120"};
		for (String label : labelArr) {
			Map<String,Object> map = new HashMap<>(2);
			map.put("label",label);
			map.put("v1",0);
			if(labelArr[0].equals(label)){
				map.put("v1",buildingPlanList.stream().filter(e -> e.getTypeStatus().equals(MaintainPlanContentEnum.MAINTAIN_WX.getId())
					&& Func.isNotEmpty(e.getArriveDuration())
					&& e.getArriveDuration() <= 30*60*1000).map(PlanWeeklyListDTO::getPlanId).distinct().count());
			}
			if(labelArr[1].equals(label)){
				map.put("v1",buildingPlanList.stream().filter(e -> e.getTypeStatus().equals(MaintainPlanContentEnum.MAINTAIN_WX.getId())
					&& Func.isNotEmpty(e.getArriveDuration())
					&& e.getArriveDuration() > 30*60*1000
					&& e.getArriveDuration() <= 60*60*1000).map(PlanWeeklyListDTO::getPlanId).distinct().count());
			}
			if(labelArr[2].equals(label)){
				map.put("v1",buildingPlanList.stream().filter(e -> e.getTypeStatus().equals(MaintainPlanContentEnum.MAINTAIN_WX.getId())
					&& Func.isNotEmpty(e.getArriveDuration())
					&& e.getArriveDuration() > 60*60*1000
					&& e.getArriveDuration() <= 90*60*1000).map(PlanWeeklyListDTO::getPlanId).distinct().count());
			}
			if(labelArr[3].equals(label)){
				map.put("v1",buildingPlanList.stream().filter(e -> e.getTypeStatus().equals(MaintainPlanContentEnum.MAINTAIN_WX.getId())
					&& Func.isNotEmpty(e.getArriveDuration())
					&& e.getArriveDuration() > 90*60*1000
					&& e.getArriveDuration() <= 120*60*1000).map(PlanWeeklyListDTO::getPlanId).distinct().count());
			}
			if(labelArr[4].equals(label)){
				map.put("v1",buildingPlanList.stream().filter(e -> e.getTypeStatus().equals(MaintainPlanContentEnum.MAINTAIN_WX.getId())
					&& Func.isNotEmpty(e.getArriveDuration())
					&& e.getArriveDuration() > 120*60*1000).map(PlanWeeklyListDTO::getPlanId).distinct().count());
			}
			result.add(map);
		}
		return result;
	}

	private List<Map<String,Object>> initMalElevatorTrend(String weekBeginTime, String weekEndTime) {
		List<Map<String,Object>> result = new ArrayList<>();
		List<String> dateList = getBetweenDate(weekBeginTime,weekEndTime);
		dateList.forEach(e -> {
			Map<String,Object> map = new HashMap<>(3);
			map.put("label",e);
			map.put("v1",0);
			map.put("v2",0);
			result.add(map);
		});
		return result;
	}

	@Override
	public Map<String, Object> repairPlanListTitleCount(WeeklyReportRepairListPageDTO weeklyReportRepairListPageDTO) {
		return baseMapper.repairPlanListTitleCount(weeklyReportRepairListPageDTO);
	}

	@Override
	public List<WeeklyReportRescueListPageVO> planViewRescueListTitleCount(IPage<WeeklyReportRescueListPageVO> page, WeeklyReportRescueListPageDTO weeklyReportRescueListPageDTO) {
		IPage<WeeklyReportRescueListPageVO> weeklyReportRescueListPageVOIPage = baseMapper.planViewRescuePage(page, weeklyReportRescueListPageDTO);
		return weeklyReportRescueListPageVOIPage.getRecords();
	}

	@Override
	public List<WeeklyReportRepairListPageVO> planViewRepairListTitleCount(IPage<WeeklyReportRepairListPageVO> page, WeeklyReportRepairListPageDTO weeklyReportRepairListPageDTO) {
		IPage<WeeklyReportRepairListPageVO> weeklyReportRepairListPageVOIPage = baseMapper.planViewRepairListPage(page, weeklyReportRepairListPageDTO);
		return weeklyReportRepairListPageVOIPage.getRecords();
	}

	/**
	 * 获取一段时间的每一天日期
	 *
	 * @param start
	 * @param end
	 * @return
	 * @throws Exception
	 */
	private static List<String> getBetweenDate(String start, String end) {
		List<String> list = new ArrayList<>();
		LocalDate startDate = LocalDate.parse(start);
		LocalDate endDate = LocalDate.parse(end);
		long distance = ChronoUnit.DAYS.between(startDate, endDate);
		if (distance < 1) {
			return list;
		}
		Stream.iterate(startDate, d -> d.plusDays(1)).limit(distance + 1).forEach(f -> list.add(f.toString()));
		return list;
	}


}
